import os
from typing import Optional, List


class FileExtensionUtil:
    """
    文件后缀名工具类
    用于获取、验证和处理文件路径的后缀信息
    """

    @staticmethod
    def get_extension(file_path: str, with_dot: bool = True, lower_case: bool = True) -> Optional[str]:
        """
        获取文件路径的后缀名

        Args:
            file_path: 文件路径
            with_dot: 是否包含点号，默认包含（如：".jpg"）
            lower_case: 是否转换为小写，默认转换

        Returns:
            文件后缀名，如果无法获取则返回None
        """
        if not file_path or not isinstance(file_path, str):
            return None

        # 获取基础文件名
        filename = os.path.basename(file_path)

        # 分割文件名和扩展名
        name, ext = os.path.splitext(filename)

        # 如果没有扩展名
        if not ext:
            return None

        # 处理扩展名格式
        result = ext
        if not with_dot and result.startswith('.'):
            result = result[1:]
        if lower_case:
            result = result.lower()

        return result

    @staticmethod
    def has_extension(file_path: str, extensions: List[str]) -> bool:
        """
        检查文件是否具有指定的后缀名之一

        Args:
            file_path: 文件路径
            extensions: 后缀名列表（可包含或不包含点号，如 ["jpg", ".png"]）

        Returns:
            如果文件具有指定的后缀名之一则返回True
        """
        file_ext = FileExtensionUtil.get_extension(file_path, with_dot=False, lower_case=True)
        if not file_ext:
            return False

        # 标准化比较的后缀名
        normalized_exts = [ext.lower().replace('.', '') for ext in extensions]

        return file_ext in normalized_exts

    @staticmethod
    def is_image_file(file_path: str) -> bool:
        """
        检查文件是否为图片文件

        Args:
            file_path: 文件路径

        Returns:
            如果是图片文件返回True
        """
        image_extensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'tiff', 'tif', 'ico', 'svg']
        return FileExtensionUtil.has_extension(file_path, image_extensions)

    @staticmethod
    def change_extension(file_path: str, new_extension: str) -> str:
        """
        更改文件路径的后缀名

        Args:
            file_path: 原文件路径
            new_extension: 新的后缀名（可包含或不包含点号）

        Returns:
            更改后缀名后的文件路径
        """
        if not file_path:
            return file_path

        # 确保新后缀名以点号开头
        if new_extension and not new_extension.startswith('.'):
            new_extension = '.' + new_extension

        # 分割路径并替换扩展名
        base_path = os.path.splitext(file_path)[0]
        return base_path + new_extension

    @staticmethod
    def get_filename_without_extension(file_path: str) -> str:
        """
        获取不包含后缀名的文件名

        Args:
            file_path: 文件路径

        Returns:
            不包含后缀名的文件名
        """
        if not file_path:
            return ""

        filename = os.path.basename(file_path)
        name, _ = os.path.splitext(filename)
        return name